import asyncio import asyncio.coroutines import logging import random import sys from cexio.exceptions import * from cexio.messaging import * from cexio.ws_client import * from config.my_config import config logger = logging.getLogger(__name__) logger.level = logging.DEBUG logger.addHandler(logging.StreamHandler(sys.stdout)) class SampleWSClient(CommonWebSocketClient): # Class responsible to setup specific messaging primitives and event model # to the instance of CEXWebSocketClientProtocol, created and connected by asyncio # This sample uses async callbacks to cover push notification (on_tick) def __init__(self, _config): super().__init__(_config) def validator(m): try: ok = m['ok'] if ok == 'ok': return m['data'] elif ok == 'error': raise ErrorMessage(m['data']['error']) else: error = InvalidMessage(m) except KeyError: error = InvalidMessage(m) raise error resolver = RequestResponseFutureResolver(name='', op_name_get_path='e', key_set_path='oid', key_get_path='oid') self.message_map = ( ({ 'e': None, 'data': None, 'oid': None, 'ok': None, }, resolver + validator), ({ 'e': None, }, self.on_notification), ) router = MessageRouter(self.message_map, sink=self.on_unhandled) self.set_router(router) self.set_resolver(resolver) self.__n_future = None self.__n_cond = asyncio.Condition() async def on_notification(self, data): print(data) return data @staticmethod def format_message(op_name, data=None): message = {'e': op_name, } if data is not None: message['data'] = data return message @staticmethod async def on_error(message): print("Error: ", message) @staticmethod async def on_unexpected_response(message): logger.debug("Resolver not expected response: {}".format(message)) return message # pass back to the router to continue matching @staticmethod async def on_unhandled(message): logger.debug("Unhandled message: {}".format(message)) print("Unhandled: {}:".format(message)) if __name__ == "__main__": client = SampleWSClient(config) async def test01(): try: balance = await client.request(SampleWSClient.format_message('get-balance')) print(balance) ticker = await client.request(SampleWSClient.format_message('ticker', ['BTC', 'USD'])) print(ticker) await client.send_subscribe({'e': 'subscribe', 'rooms': ['tickers', ],}) await client.send_subscribe({ "e": "init-ohlcv-new", "i": "1m", "rooms": ["pair-BTC-USD"]}) await client.request_subscribe(SampleWSClient.format_message( 'order-book-subscribe', { 'pair': [ 'BTC', 'USD', ], 'subscribe': 'true', 'depth': 12, })) except Exception as ex: logger.error(ex) # to test reconnecting async def _get_balance(): while True: try: await asyncio.sleep(random.randrange(12, 32)) balance = await client.request(SampleWSClient.format_message('get-balance')) print(balance) except Exception as ex: print("Exception at closing connection: {}".format(ex)) # to test reconnecting async def _force_disconnect(): while True: try: await asyncio.sleep(random.randrange(24, 64)) print('test > Force disconnect') await client.ws.close() except Exception as ex: print("Exception at exit: {}".format(ex), sys.__stderr__) loop = asyncio.get_event_loop() loop.set_debug(True) loop.run_until_complete(client.run()) tasks = [ asyncio.ensure_future(test01()), asyncio.ensure_future(_get_balance()), asyncio.ensure_future(_force_disconnect()), ] loop.run_until_complete(asyncio.wait(tasks)) loop.run_forever() loop.close() else: pass